#ifndef NETWORK_MESSAGE_H
#define NETWORK_MESSAGE_H

/*
 * NetworkMessage.h
 * @author: tfischer
 * 
 * Represents a message with a size, type and body
 * that came or is going trough a network
 * 
 * */

#include <string.h>

#include "../utils/data_types.h"

#ifndef NULL
#define NULL 0
#endif

class NetworkMessage
{
    public:
        
        /* 
         * Recieves the raw header data, decodes it,
         * and encodes it into the local data 
         * */
        
        NetworkMessage(uint8* header_data);
        
        /*
         * Recieves the header data, copies it, 
         * and encodes it into the local data 
         * */
        NetworkMessage(msg_t type, size_t body_length);
        
        /* 
         * Get the message lengrh of the whole data blocke
         *  */
        size_t GetLength() const;
        
        /* 
         * Get the message lengrh of the body
         *  */
        static size_t GetHeaderLength();
        
        /* 
         * Get the message lengrh of the body
         *  */
        size_t GetBodyLength() const;
        
        /* 
         * Get the message type
         *  */
        msg_t GetType() const;
        
        /*
         * Exposes the whole data block ( header + body )
         * possibly to send it trough the network
         * */
        const uint8* GetData() const;
        
        /*
         * Exposes the whole body data block
         * possibly to buffer the incoming message body
         * */
        uint8* GetHeader();
        
        /*
         * Exposes the whole body data block
         * possibly to buffer the incoming message body
         * */
        uint8* GetBody();
        
        /*
         * Copies body data to the data block
         * */
        void EncodeBody(const uint8* body_data);
        
    private:
        
        uint8* _data;
        
        // :TODO: @author tfischer
        // type no deberia ser parte de esta clase
        // deberia estar en un nivel mas de encapsulamiento.
        // Esta aca pensando en performance por ahora
        msg_t _type;
        
        size_t _body_length;
        
        enum { HEADER_LENGTH = sizeof(size_t) + sizeof(msg_t) };
        
        /*
         * Decode the header info from a header data block
         * */
        void DecodeHeader(uint8* header_data);
        
        /*
         * Encodes the header info into the data block
         * */
        void EncodeHeader();
};

#endif
